package com.yan.design.two.establish.s3;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.*;
import java.util.Date;

/**
 * 三.原型模式
 *      浅拷贝
 * @author shengren.yan
 * @create 2022-07-17
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Prototype1 implements Serializable,Cloneable{

    private String name;
    private Date createTime;
    private Dep dep;

    // A 重写 clone方法 ---- 浅拷贝
//    @Override
//    protected Object clone() throws CloneNotSupportedException {
//        return super.clone();
//    }


    // B 重写 clone方法 ---- 深拷贝  实现方式1：
//    @Override
//    protected Object clone() throws CloneNotSupportedException {
//        Object obj = null;
//        obj = super.clone();
//        Prototype1 p = (Prototype1) obj;
//        p.dep = (Dep) dep.clone();  // 深拷贝
//        return p;
//    }

    // B ---- 深拷贝  实现方式2： 通过反序列化
    public Object doClone() {
        // 创建流
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        try {
            // 序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);  // 当前对象以对象流方式输出

            // 反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            Prototype1 p = (Prototype1) ois.readObject();
            return p;

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    // B ---- 深拷贝  实现方式2： 通过反序列化  -- 需要实现序列化接口
    public Object deepCopy(Object object) throws Exception {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(bo);
        oo.writeObject(object);
        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi = new ObjectInputStream(bi);
        return oi.readObject();
    }

}
